//
// * Copyright (c) 2002-2009 "Neo Technology,"
// *     Network Engine for Objects in Lund AB [http://neotechnology.com]
// *
// * This file is part of Neo4j.
// * 
// * Neo4j is free software: you can redistribute it and/or modify
// * it under the terms of the GNU Affero General Public License as
// * published by the Free Software Foundation, either version 3 of the
// * License, or (at your option) any later version.
// * 
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU Affero General Public License for more details.
// * 
// * You should have received a copy of the GNU Affero General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
namespace org.neo4j.kernel.impl.traversal
{

//JAVA TO VB & C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
	import static org.neo4j.graphdb.Traverser.Order.BREADTH_FIRST;
//JAVA TO VB & C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
	import static org.neo4j.graphdb.Traverser.Order.DEPTH_FIRST;

	using Direction = org.neo4j.graphdb.Direction;
	using Node = org.neo4j.graphdb.Node;
	using NotFoundException = org.neo4j.graphdb.NotFoundException;
	using Relationship = org.neo4j.graphdb.Relationship;
	using RelationshipType = org.neo4j.graphdb.RelationshipType;
	using ReturnableEvaluator = org.neo4j.graphdb.ReturnableEvaluator;
	using StopEvaluator = org.neo4j.graphdb.StopEvaluator;
	using TraversalPosition = org.neo4j.graphdb.TraversalPosition;
	using Traverser = org.neo4j.graphdb.Traverser;
	using Order = org.neo4j.graphdb.Traverser.Order;
	using AbstractNeo4jTestCase = org.neo4j.kernel.impl.AbstractNeo4jTestCase;
	using MyRelTypes = org.neo4j.kernel.impl.MyRelTypes;

	public class TestTraversal : AbstractNeo4jTestCase
	{
		public TestTraversal(string testName) : base(testName)
		{
		}

	// -- Test operations

	// Tests the traverser factory for sanity checks with corrupted input
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testSanityChecks1() throws Exception
		public virtual void testSanityChecks1()
		{
		// Valid data
			Node root = getGraphDb().createNode();
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };
		// Null traversable relationships
			this.sanityCheckTraverser("Sanity check failed: null traversable " + "rels should throw an " + "IllegalArgumentException", BREADTH_FIRST, root, null, Direction.OUTGOING, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL);

		// Null stop evaluator
			this.sanityCheckTraverser("Sanity check failed: null stop eval " + "should throw an IllegalArgumentException", BREADTH_FIRST, root, traversableRels[0], Direction.OUTGOING, null, ReturnableEvaluator.ALL);

		// Null returnable evaluator
			this.sanityCheckTraverser("Sanity check failed: null returnable " + "evaluator should throw an " + "IllegalArgumentException", BREADTH_FIRST, root, traversableRels[0], Direction.OUTGOING, StopEvaluator.END_OF_GRAPH, null);
			root.delete();
		}

//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testSanityChecks2() throws Exception
		public virtual void testSanityChecks2()
		{
		// ------------- with traverser direction -------------
		// Valid data
			Node root = getGraphDb().createNode();
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };
			Direction[] traversableDirs = new Direction[] { Direction.OUTGOING };

		// Null traversable relationships
			this.sanityCheckTraverser("Sanity check failed: null traversable " + "rels should throw an " + "IllegalArgumentException", BREADTH_FIRST, root, null, traversableDirs[0], StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL);

		// Null traversable directions
			this.sanityCheckTraverser("Sanity check failed: null traversable " + "rels should throw an " + "IllegalArgumentException", BREADTH_FIRST, root, traversableRels[0], null, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL);

		// Null stop evaluator
			this.sanityCheckTraverser("Sanity check failed: null stop eval " + "should throw an IllegalArgumentException", BREADTH_FIRST, root, traversableRels[0], traversableDirs[0], null, ReturnableEvaluator.ALL);

		// Null returnable evaluator
			this.sanityCheckTraverser("Sanity check failed: null returnable " + "evaluator should throw an " + "IllegalArgumentException", BREADTH_FIRST, root, traversableRels[0], traversableDirs[0], StopEvaluator.END_OF_GRAPH, null);
		// traversable relationships length not equal to traversable directions
		// length
			this.sanityCheckTraverser("Sanity check failed: null returnable " + "evaluator should throw an " + "IllegalArgumentException", BREADTH_FIRST, root, traversableRels[0], null, StopEvaluator.END_OF_GRAPH, null);
			this.sanityCheckTraverser("Sanity check failed: null returnable " + "evaluator should throw an " + "IllegalArgumentException", BREADTH_FIRST, root, null, traversableDirs[0], StopEvaluator.END_OF_GRAPH, null);
			root.delete();
		}

	// Tests the traverser factory for simple corrupted (null) input, used
	// by testSanityChecks()
		private void sanityCheckTraverser(string failMessage, Order type, Node startNode, RelationshipType traversableRel, Direction direction, StopEvaluator stopEval, ReturnableEvaluator retEval)
		{
			try
			{
				startNode.traverse(type, stopEval, retEval, traversableRel, direction);
				fail(failMessage);
			}
			catch (IllegalArgumentException iae)
			{
			// This is ok
			}
		}

		private void sanityCheckTraverser(string failMessage, Order type, Node startNode, RelationshipType traversableRel1, Direction direction1, RelationshipType traversableRel2, Direction direction2, StopEvaluator stopEval, ReturnableEvaluator retEval)
		{
			try
			{
				startNode.traverse(type, stopEval, retEval, traversableRel1, direction1, traversableRel2, direction2);
				fail(failMessage);
			}
			catch (IllegalArgumentException iae)
			{
			// This is ok
			}
		}

	// Traverses the full test "ise-tree-like" population breadth first
	// and verifies that it is returned in correct order
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testBruteBreadthTraversal() throws Exception
		public virtual void testBruteBreadthTraversal()
		{
			Node root = this.buildIseTreePopulation();
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST_TRAVERSAL };
			Traverser traverser = root.traverse(BREADTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH, traversableRels[1], Direction.BOTH);

			try
			{
				this.assertNextNodeId(traverser, "1");
				this.assertNextNodeId(traverser, "2");
				this.assertNextNodeId(traverser, "3");
				this.assertNextNodeId(traverser, "4");
				this.assertNextNodeId(traverser, "5");
				this.assertNextNodeId(traverser, "6");
				this.assertNextNodeId(traverser, "7");
				this.assertNextNodeId(traverser, "8");
				this.assertNextNodeId(traverser, "9");
				this.assertNextNodeId(traverser, "10");
				this.assertNextNodeId(traverser, "11");
				this.assertNextNodeId(traverser, "12");
				this.assertNextNodeId(traverser, "13");
				this.assertNextNodeId(traverser, "14");
				assertTrue("Too many nodes returned from traversal", traverser.GetEnumerator().MoveNext() == false);
			}
			catch (java.util.NoSuchElementException nsee)
			{
				fail("Too few nodes returned from traversal");
			}
			finally
			{
				this.deleteNodeTreeRecursively(root, 0);
			}
		}

	// Traverses the test "ise-tree-like" population breadth first,
	// but only traverses "ise" (TEST) relationships (the population also
	// contains
	// "ise_clone" (TEST_TRAVERSAL) rels)
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testMultiRelBreadthTraversal() throws Exception
		public virtual void testMultiRelBreadthTraversal()
		{
			Node root = this.buildIseTreePopulation();
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };
			Traverser traverser = root.traverse(BREADTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH);

			try
			{
				this.assertNextNodeId(traverser, "1");
				this.assertNextNodeId(traverser, "2");
				this.assertNextNodeId(traverser, "3");
				this.assertNextNodeId(traverser, "4");
				this.assertNextNodeId(traverser, "5");
				this.assertNextNodeId(traverser, "6");
				this.assertNextNodeId(traverser, "7");
				this.assertNextNodeId(traverser, "10");
				this.assertNextNodeId(traverser, "11");
				this.assertNextNodeId(traverser, "12");
				this.assertNextNodeId(traverser, "13");
				assertTrue("Too many nodes returned from traversal", traverser.GetEnumerator().MoveNext() == false);
			}
			catch (java.util.NoSuchElementException nsee)
			{
				fail("Too few nodes returned from traversal");
			}
			finally
			{
				this.deleteNodeTreeRecursively(root, 0);
			}
		}

	// Traverses the test "ise-tree-like" population breadth first,
	// starting in the middle of the tree and traversing only in the
	// "forward" direction
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testDirectedBreadthTraversal() throws Exception
		public virtual void testDirectedBreadthTraversal()
		{
		// Build test population
			Node root = this.buildIseTreePopulation();
			Node startNode = null;

		// Get a node in the middle of the tree:
			try
			{
			// a) Construct a returnable evaluator that returns node 2
				ReturnableEvaluator returnEvaluator = new ReturnableEvaluator();
//JAVA TO VB & C# CONVERTER TODO TASK: Anonymous inner classes are not converted to .NET:
				{
					public bool isReturnableNode(TraversalPosition pos)
					{
						try
						{
							Node node = pos.currentNode();
							string key = "node.test.id";
							string nodeId = (string) node.getProperty(key);
							return nodeId.Equals("2");
						}
						catch (Exception e)
						{
							return false;
						}
					}
				}

			// b) create a traverser
				Traverser toTheMiddleTraverser = root.traverse(BREADTH_FIRST, StopEvaluator.END_OF_GRAPH, returnEvaluator, MyRelTypes.TEST, Direction.BOTH);

			// c) get the first node it returns
				startNode = toTheMiddleTraverser.GetEnumerator().Current;
			}
			catch (Exception e)
			{
				e.printStackTrace();
				fail("Something went wrong when trying to get a start node " + "in the middle of the tree: " + e);
			}

		// Construct the real traverser
			Traverser traverser = startNode.traverse(BREADTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL, MyRelTypes.TEST, Direction.OUTGOING);
			try
			{
				this.assertNextNodeId(traverser, "2");
				this.assertNextNodeId(traverser, "5");
				this.assertNextNodeId(traverser, "6");
				this.assertNextNodeId(traverser, "10");
				this.assertNextNodeId(traverser, "11");
				this.assertNextNodeId(traverser, "12");
				this.assertNextNodeId(traverser, "13");
				assertTrue("Too many nodes returned from traversal", traverser.GetEnumerator().MoveNext() == false);
			}
			catch (java.util.NoSuchElementException nsee)
			{
				nsee.printStackTrace();
				fail("Too few nodes returned from traversal");
			}
			finally
			{
				this.deleteNodeTreeRecursively(root, 0);
			}
		}

	// Traverses the full test "ise-tree-like" population depth first
	// and verifies that it is returned in correct order
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testBruteDepthTraversal() throws Exception
		public virtual void testBruteDepthTraversal()
		{
			Node root = this.buildIseTreePopulation();
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST_TRAVERSAL };
			Traverser traverser = root.traverse(DEPTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH, traversableRels[1], Direction.BOTH);

			try
			{
				this.assertNextNodeId(traverser, "1");
				this.assertNextNodeId(traverser, "4");
				this.assertNextNodeId(traverser, "9");
				this.assertNextNodeId(traverser, "14");
				this.assertNextNodeId(traverser, "8");
				this.assertNextNodeId(traverser, "3");
				this.assertNextNodeId(traverser, "7");
				this.assertNextNodeId(traverser, "6");
				this.assertNextNodeId(traverser, "2");
				this.assertNextNodeId(traverser, "5");
				this.assertNextNodeId(traverser, "13");
				this.assertNextNodeId(traverser, "12");
				this.assertNextNodeId(traverser, "11");
				this.assertNextNodeId(traverser, "10");

			// this is another possible order, depending on traversal
			// implementation/PS
			// this.assertNextNodeId( traverser, "2" );
			// this.assertNextNodeId( traverser, "5" );
			// this.assertNextNodeId( traverser, "10" );
			// this.assertNextNodeId( traverser, "11" );
			// this.assertNextNodeId( traverser, "12" );
			// this.assertNextNodeId( traverser, "13" );
			// this.assertNextNodeId( traverser, "6" );
			// this.assertNextNodeId( traverser, "7" );
			// this.assertNextNodeId( traverser, "3" );
			// this.assertNextNodeId( traverser, "4" );
			// this.assertNextNodeId( traverser, "8" );
			// this.assertNextNodeId( traverser, "9" );
			// this.assertNextNodeId( traverser, "14" );
				assertTrue("Too many nodes returned from traversal", traverser.GetEnumerator().MoveNext() == false);
			}
			catch (java.util.NoSuchElementException nsee)
			{
				fail("Too few nodes returned from traversal");
			}
			finally
			{
				this.deleteNodeTreeRecursively(root, 0);
			}
		}

	// Traverses the test "ise-tree-like" population depth first,
	// but only traverses "ise" relationships (the population also contains
	// "ise_clone" rels)
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testMultiRelDepthTraversal() throws Exception
		public virtual void testMultiRelDepthTraversal()
		{
			Node root = this.buildIseTreePopulation();
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };
			Traverser traverser = root.traverse(DEPTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH);

			try
			{
				this.assertNextNodeId(traverser, "1");
				this.assertNextNodeId(traverser, "4");
				this.assertNextNodeId(traverser, "3");
				this.assertNextNodeId(traverser, "7");
				this.assertNextNodeId(traverser, "2");
				this.assertNextNodeId(traverser, "6");
				this.assertNextNodeId(traverser, "5");
				this.assertNextNodeId(traverser, "13");
				this.assertNextNodeId(traverser, "12");
				this.assertNextNodeId(traverser, "11");
				this.assertNextNodeId(traverser, "10");

			// this is another possible order, depends on traversal
			// implementation/PS
			// this.assertNextNodeId( traverser, "2" );
			// this.assertNextNodeId( traverser, "5" );
			// this.assertNextNodeId( traverser, "10" );
			// this.assertNextNodeId( traverser, "11" );
			// this.assertNextNodeId( traverser, "12" );
			// this.assertNextNodeId( traverser, "13" );
			// this.assertNextNodeId( traverser, "6" );
			// this.assertNextNodeId( traverser, "3" );
			// this.assertNextNodeId( traverser, "7" );
			// this.assertNextNodeId( traverser, "4" );
				assertTrue("Too many nodes returned from traversal", traverser.GetEnumerator().MoveNext() == false);
			}
			catch (java.util.NoSuchElementException nsee)
			{
				fail("Too few nodes returned from traversal");
			}
			finally
			{
				this.deleteNodeTreeRecursively(root, 0);
			}
		}

	// Verifies that the stop evaluator can stop based on the current node
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testStopOnCurrentNode() throws Exception
		public virtual void testStopOnCurrentNode()
		{
		// Build ise tree
			Node root = this.buildIseTreePopulation();

		// Traverse only ISE relationships
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };

		// Construct a stop evaluator that stops on nodes 5, 6, 3 and 4
			StopEvaluator stopEvaluator = new StopEvaluator();
//JAVA TO VB & C# CONVERTER TODO TASK: Anonymous inner classes are not converted to .NET:
			{
				public bool isStopNode(TraversalPosition position)
				{
					try
					{
						Node node = position.currentNode();

						string nodeId = (string) node.getProperty("node.test.id");
						return nodeId.Equals("5") || nodeId.Equals("6") || nodeId.Equals("3") || nodeId.Equals("4");
					}
					catch (Exception e)
					{
						return false;
					}
				}
			}

		// Create a traverser
			Traverser traverser = root.traverse(BREADTH_FIRST, stopEvaluator, ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH);

			try
			{
				this.assertNextNodeId(traverser, "1");
				this.assertNextNodeId(traverser, "2");
				this.assertNextNodeId(traverser, "3");
				this.assertNextNodeId(traverser, "4");
				this.assertNextNodeId(traverser, "5");
				this.assertNextNodeId(traverser, "6");

				assertTrue("Too many nodes returned from traversal", traverser.GetEnumerator().MoveNext() == false);
			}
			catch (java.util.NoSuchElementException nsee)
			{
				fail("Too few nodes returned from traversal");
			}
			finally
			{
				this.deleteNodeTreeRecursively(root, 0);
			}
		}

	// Verifies that the stop evaluator can stop based on the previous node
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testStopOnPreviousNode() throws Exception
		public virtual void testStopOnPreviousNode()
		{
		// Build ise tree
			Node root = this.buildIseTreePopulation();

		// Traverse only ISE relationships
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };

		// Construct a stop evaluator that stops on nodes 2, 3, and 4
		// (ie root's children)
			StopEvaluator stopEvaluator = new StopEvaluator();
//JAVA TO VB & C# CONVERTER TODO TASK: Anonymous inner classes are not converted to .NET:
			{
				public bool isStopNode(TraversalPosition position)
				{
					try
					{
						Node node = position.previousNode();
						string nodeId = (string) node.getProperty("node.test.id");
						return nodeId.Equals("1");
					}
					catch (Exception e)
					{
						return false;
					}
				}
			}

		// Create a traverser
			Traverser traverser = root.traverse(BREADTH_FIRST, stopEvaluator, ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH);

			try
			{
				this.assertNextNodeId(traverser, "1");
				this.assertNextNodeId(traverser, "2");
				this.assertNextNodeId(traverser, "3");
				this.assertNextNodeId(traverser, "4");

				assertTrue("Too many nodes returned from traversal", traverser.GetEnumerator().MoveNext() == false);
			}
			catch (java.util.NoSuchElementException nsee)
			{
				fail("Too few nodes returned from traversal");
			}
			finally
			{
			// Delete ise tree and commmit work
				this.deleteNodeTreeRecursively(root, 0);
			}
		}

	// Verifies that the stop evaluator can stop based on the current depth
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testStopOnDepth() throws Exception
		public virtual void testStopOnDepth()
		{
		// Build ise tree
			Node root = this.buildIseTreePopulation();

		// Traverse only ISE relationships
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };

		// Construct a stop evaluator that stops on depth 2
			StopEvaluator stopEvaluator = new StopEvaluator();
//JAVA TO VB & C# CONVERTER TODO TASK: Anonymous inner classes are not converted to .NET:
			{
				public bool isStopNode(TraversalPosition position)
				{
					return position.depth() >= 2;
				}
			}

		// Create a traverser
			Traverser traverser = root.traverse(BREADTH_FIRST, stopEvaluator, ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH);

			try
			{
				this.assertNextNodeId(traverser, "1");
				this.assertNextNodeId(traverser, "2");
				this.assertNextNodeId(traverser, "3");
				this.assertNextNodeId(traverser, "4");
				this.assertNextNodeId(traverser, "5");
				this.assertNextNodeId(traverser, "6");
				this.assertNextNodeId(traverser, "7");

				assertTrue("Too many nodes returned from traversal", traverser.GetEnumerator().MoveNext() == false);
			}
			catch (java.util.NoSuchElementException nsee)
			{
				fail("Too few nodes returned from traversal");
			}
			finally
			{
			// Delete ise tree and commmit work
				this.deleteNodeTreeRecursively(root, 0);
			}
		}

	// Verifies that the stop evaluator can stop based on the amount of
	// returned nodes
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testStopOnReturnedNodes() throws Exception
		public virtual void testStopOnReturnedNodes()
		{
		// Build ise tree
			Node root = this.buildIseTreePopulation();

		// Traverse only ISE relationships
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };

		// Construct stop- and returnable evaluators that return 5 nodes
			StopEvaluator stopEvaluator = new StopEvaluator();
//JAVA TO VB & C# CONVERTER TODO TASK: Anonymous inner classes are not converted to .NET:
			{
				public bool isStopNode(TraversalPosition position)
				{
				// Stop traversing when we've returned 5 nodes
					return position.returnedNodesCount() >= 5;
				}
			}
			ReturnableEvaluator returnEvaluator = new ReturnableEvaluator();
//JAVA TO VB & C# CONVERTER TODO TASK: Anonymous inner classes are not converted to .NET:
			{
				public bool isReturnableNode(TraversalPosition position)
				{
				// Return nodes until we've reached 5 nodes or end of graph
					return position.returnedNodesCount() < 5;
				}
			}

		// Create a traverser
			Traverser traverser = root.traverse(BREADTH_FIRST, stopEvaluator, returnEvaluator, traversableRels[0], Direction.BOTH);

			try
			{
				this.assertNextNodeId(traverser, "1");
				this.assertNextNodeId(traverser, "2");
				this.assertNextNodeId(traverser, "3");
				this.assertNextNodeId(traverser, "4");
				this.assertNextNodeId(traverser, "5");

				assertTrue("Too many nodes returned from traversal", traverser.GetEnumerator().MoveNext() == false);
			}
			catch (java.util.NoSuchElementException nsee)
			{
				fail("Too few nodes returned from traversal");
			}
			finally
			{
			// Delete ise tree and commmit work
				this.deleteNodeTreeRecursively(root, 0);
			}
		}

	// Verifies that the stop evaluator can stop based on the last
	// traversed relationship
//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void testStopOnLastRelationship() throws Exception
		public virtual void testStopOnLastRelationship()
		{
		// Build ise tree
			Node root = this.buildIseTreePopulation();

		// Traverse only ISE relationships
			RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST_TRAVERSAL };

		// Construct stop- and returnable evaluators that return 5 nodes
			StopEvaluator stopEvaluator = new StopEvaluator();
//JAVA TO VB & C# CONVERTER TODO TASK: Anonymous inner classes are not converted to .NET:
			{
				public bool isStopNode(TraversalPosition position)
				{
				// Stop when we got here by traversing a clone relationship
					Relationship rel = position.lastRelationshipTraversed();
					return rel != null && rel.getType() == MyRelTypes.TEST_TRAVERSAL;
				}
			}

		// Create a traverser
			Traverser traverser = root.traverse(BREADTH_FIRST, stopEvaluator, ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH, traversableRels[1], Direction.BOTH);

			try
			{
				this.assertNextNodeId(traverser, "1");
				this.assertNextNodeId(traverser, "2");
				this.assertNextNodeId(traverser, "3");
				this.assertNextNodeId(traverser, "4");
				this.assertNextNodeId(traverser, "5");
				this.assertNextNodeId(traverser, "6");
				this.assertNextNodeId(traverser, "7");
				this.assertNextNodeId(traverser, "8");
				this.assertNextNodeId(traverser, "9");
				this.assertNextNodeId(traverser, "10");
				this.assertNextNodeId(traverser, "11");
				this.assertNextNodeId(traverser, "12");
				this.assertNextNodeId(traverser, "13");

				assertTrue("Too many nodes returned from traversal", traverser.GetEnumerator().MoveNext() == false);
			}
			catch (java.util.NoSuchElementException nsee)
			{
				fail("Too few nodes returned from traversal");
			}
			finally
			{
			// Delete ise tree and commmit work
				this.deleteNodeTreeRecursively(root, 0);
			}
		}

	// -- Utility operations

		private Node buildIseTreePopulation()
	// throws CreateException
		{
			try
			{
			// Create population
				Node[] nodeSpace = new Node[] { null, getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode(), getGraphDb().createNode() };

				string key = "node.test.id";
				for (int i = 1; i < nodeSpace.Length; i++)
				{
					nodeSpace[i].setProperty(key, "" + i);
				}

				RelationshipType ise = MyRelTypes.TEST;
				RelationshipType clone = MyRelTypes.TEST_TRAVERSAL;

			// Bind it together
				nodeSpace[1].createRelationshipTo(nodeSpace[2], ise);
				nodeSpace[2].createRelationshipTo(nodeSpace[5], ise);
				nodeSpace[5].createRelationshipTo(nodeSpace[10], ise);
				nodeSpace[5].createRelationshipTo(nodeSpace[11], ise);
				nodeSpace[5].createRelationshipTo(nodeSpace[12], ise);
				nodeSpace[5].createRelationshipTo(nodeSpace[13], ise);
				nodeSpace[2].createRelationshipTo(nodeSpace[6], ise);
				nodeSpace[1].createRelationshipTo(nodeSpace[3], ise);
				nodeSpace[1].createRelationshipTo(nodeSpace[4], ise);
				nodeSpace[3].createRelationshipTo(nodeSpace[7], ise);

				nodeSpace[6].createRelationshipTo(nodeSpace[7], clone);
				nodeSpace[4].createRelationshipTo(nodeSpace[8], clone);
				nodeSpace[4].createRelationshipTo(nodeSpace[9], clone);
				nodeSpace[9].createRelationshipTo(nodeSpace[14], clone);

				return nodeSpace[1]; // root
			}
			catch (Exception e)
			{
				throw new RuntimeException("Failed to create population", e);
			}
		}

	// Deletes a tree-like structure of nodes, starting with 'currentNode'.
	// Works fine with trees, dies horribly on cyclic structures.
		private void deleteNodeTreeRecursively(Node currentNode, int depth)
		{
			if (depth > 100)
			{
				throw new RuntimeException("Recursive guard: depth = " + depth);
			}

			if (currentNode == null)
			{
				return;
			}

			Iterable<Relationship> rels = currentNode.getRelationships();
			foreach (Relationship rel in rels)
			{
				if (!rel.getStartNode().Equals(currentNode))
				{
					continue;
				}
				Node endNode = rel.getEndNode();
				rel.delete();
				this.deleteNodeTreeRecursively(endNode, depth + 1);
			}
			try
			{
				string msg = "Deleting " + currentNode + "\t[";
				string id = (string) currentNode.getProperty("node.test.id");
				msg += id + "]";
			}
			catch (Exception e)
			{
				System.err.println("Err gen msg: " + e);
			}

			Iterable<Relationship> allRels = currentNode.getRelationships();
			foreach (Relationship rel in allRels)
			{
				rel.delete();
			}
			currentNode.delete();
		}

//JAVA TO VB & C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private void assertNextNodeId(Traverser traverser, String property) throws NotFoundException
		private void assertNextNodeId(Traverser traverser, string property)
		{
			Node node = traverser.GetEnumerator().Current;
			assertEquals(property, node.getProperty("node.test.id"));
		}
	}

}